#include "ffplayer.h"
#include "ffplay_stater.h"
#define SDL_AUDIO_MIN_BUFFER_SIZE 512
FFPlayer::FFPlayer()
{

}
int vidindex = -1;
int FFPlayer::ffp_create()
{
    int ret =0 ;
    msg_queue_init(&this->msg_queue_);
    av_init_packet(&flush_pkt);
    memset(&flush_pkt,0,sizeof(AVPacket));
    flush_pkt.data = (uint8_t *)&flush_pkt;

    return ret;
}

int FFPlayer::ffp_prepare_async_l(char *filename)
{
    int ret =0;
    this->input_filename_ = strdup(filename);
    ret = stream_open(filename);
    return ret;
}

int FFPlayer::stream_open(char *filename)
{
    if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER))
    {
        av_log(NULL, AV_LOG_FATAL, "Could not initialize SDL - %s\n", SDL_GetError());
        av_log(NULL, AV_LOG_FATAL, "(Did you set the DISPLAY variable?)\n");
        return -1;
    }
    //初始化pakqueue 和 framequeue
    int ret =0;
    ret = packet_queue_init(&this->vidpq);
    if(ret<0){
        stream_close();
        return -1;
    }
    ret = packet_queue_init(&this->audpq);
    if(ret<0){
        stream_close();
        return -1;
    }

    ret = frame_queue_init(&this->vidpq,&this->vidfq,VIDEO_PICTURE_QUEUE_SIZE_DEFAULT);
    if (ret<0){
        stream_close();
        return -1;
    }
    ret = frame_queue_init(&this->audpq,&this->audfq,SAMPLE_QUEUE_SIZE);
    if(ret<0){
        stream_close();
        return -1;
    }
    
    read_thread_ = new std::thread(&FFPlayer::read_thread,this);
    video_refresh_thread_ = new std::thread(&FFPlayer::refresh_thread,this);
    return ret ;
}

int FFPlayer::stream_close()
{
    this->abort_request=1;
    int ret =0 ;
    //释放读线程
    if(this->read_thread_ && this->read_thread_->joinable()){
        this->read_thread_->join();
    }
    if(this->video_refresh_thread_ && this->video_refresh_thread_->joinable()){
        this->video_refresh_thread_->join();
    }
    //释放codec
    ret = stream_componnet_close(this->audio_stream);
    if(ret<0){

    }
    ret = stream_componnet_close(this->video_stream);
    if(ret<0){

    }
    avformat_close_input(&(this->avfmt));
    //frame_queue_destroy

    //释放pktqueue
    ret= pakcet_queue_destroy(&this->vidpq);
    if(ret<0){

    }
    //pakcet_queue_destroy
    //pakcet_queue_destroy
    ret= pakcet_queue_destroy(&this->audpq);
    if(ret<0){

    }//packet_queue_dest

    //释放framequeue
    ret= frame_queue_destroy(&this->audfq);
    if(ret<0){

    }
    ret= frame_queue_destroy(&this->vidfq);
    if(ret<0){

    }
    //释放上下文
    //释放各种东西

    return 0;
}

int FFPlayer::read_thread()
{
    //准备流程
    AVFormatContext *ctx = NULL;
    int stream_index[AVMEDIA_TYPE_NB];
    int ret =0 ;
//    memset(stream_index,sizeof(stream_index),-1);
    //设置索引
    memset(stream_index,-1,sizeof(stream_index));
//    stream_index[AVMEDIA_TYPE_AUDIO] =-1;
//    stream_index[AVMEDIA_TYPE_VIDEO] =-1;


    //设置索引
    //创建上下文结构体
    ctx = avformat_alloc_context();

    //设置回调函数
    //打开文件,探测类型
    ret = avformat_open_input(&ctx,this->input_filename_,NULL,NULL);
    if(ret<0){
        std::cout<<"avformat_open_input error"<<std::endl;
        return -1;
    }

    msg_queue_put_simple1(&this->msg_queue_,FFP_MSG_OPEN_INPUT);

    //std::cout<<__FUNCTION__<<":open input"<<std::endl;

    ret = avformat_find_stream_info(ctx,NULL);
    if(ret<0){
        std::cout<<"avformat_find_stream_info error"<<std::endl;
    }

    msg_queue_put_simple1(&this->msg_queue_,FFP_MSG_FIND_STREAM_INFO);
    // std::cout<<__FUNCTION__<<":FIND_STREAM_INFO"<<std::endl;
    this->avfmt = ctx;
    //判断是否有起始流,或者是否有默认开始位置
    //判断是否为实时流(可以省略把)
    //查找流
    stream_index[AVMEDIA_TYPE_AUDIO] =
            av_find_best_stream(
                ctx,
                AVMEDIA_TYPE_AUDIO,
                stream_index[AVMEDIA_TYPE_AUDIO],
                -1,
                NULL,
                0);

    stream_index[AVMEDIA_TYPE_VIDEO] =
            av_find_best_stream(
                ctx,
                AVMEDIA_TYPE_VIDEO,
                stream_index[AVMEDIA_TYPE_VIDEO],
                stream_index[AVMEDIA_TYPE_AUDIO],
                NULL,
                0);

    //找到对应流?
    //修改数据???
    //打开解码器(stream_compent_open
    if(stream_index[AVMEDIA_TYPE_AUDIO]>=0){
        this->audio_stream=stream_index[AVMEDIA_TYPE_AUDIO];
        stream_componnet_open(stream_index[AVMEDIA_TYPE_AUDIO]);
    }
    if(stream_index[AVMEDIA_TYPE_VIDEO]>=0){
        this->video_stream=stream_index[AVMEDIA_TYPE_VIDEO];
        vidindex = video_stream;
        stream_componnet_open(stream_index[AVMEDIA_TYPE_VIDEO]);
    }
    //进入循环

    ffp_notify_msg1(this, FFP_MSG_PREPARED);
    //for(;;)
    AVPacket pkt1;
    AVPacket *pkt=&pkt1 ;
    for(;;){
        if(this->abort_request){
            std::cout<<__LINE__<<"read thread break"<<std::endl;
            break;
        }
        //是否进行seek
        if(this->seek){
          this->seek = 0;
        };
        //strattime

        ret = av_read_frame(this->avfmt,pkt);
        //没有读取到包
        if(ret<0){
            int eof=0;
            //读取到文件尾部
            if((ret == AVERROR_EOF || avio_feof(ctx->pb)) && this->eof) {
                if(this->audio_stream>=0){
                    eof = packet_queue_put_nullpkt(&this->audpq,this->audio_stream);
                    if(eof<0){
                        return -100;
                    }
                }
                if(this->video_stream>=0){
                    eof = packet_queue_put_nullpkt(&this->vidpq,this->video_stream);
                    if(eof<0){
                        return -100;
                    }
                }
            }
         }
        if(pkt->stream_index == this->audio_stream){
            packet_queue_put(&this->audpq,pkt);
        }else if(pkt->stream_index == this->video_stream){
//            av_packet_unref(pkt);
            packet_queue_put(&this->vidpq,pkt);
        }else {
            av_packet_unref(pkt);
        }
//         std::cout<<__FUNCTION__<<"is running"<<std::endl;
    }
    return stream_close();

}

//int FFPlayer::()
//{

//    for(;;){

//        refersh_video();

//    }
//}
const double refresh_time = 0.01;

void FFPlayer::refresh_thread()
{
    double remaining_time = 0.0;
    while(!abort_request){
        if(remaining_time){
            av_usleep((int)remaining_time*10000000 );

        }
      //  remaining_time = refresh_time;
        video_refresh(&remaining_time);
    }
    std::cout<<"refresh end"<<std::endl;
}

//void FFPlayer::addVidep_refresh_thread()
//{

//}
// 需要应该容忍值,最大值和最小值
// 就按照那个来写吧,记录上一帧和两帧差值作为输出

int FFPlayer::video_refresh(double *re_time)
{
    Frame *frame = NULL;
    Frame *last_frame = NULL:
    if(st_video){
        if(frame_queue_nb_remaining(&vidfq)==0){
            return -1;
        }
        frame= frame_queue_get(&vidfq);
//        double delay
        last_frame = frame_queue_get_last(&vidfq);



        double duration = get_duration();
        double time = av_gettime_relative()/ 1000000.0;
        double time_n = this->master_clock.get_clock();

        double cha = time + time_n;
        if(cha > frame->pts ){
            if(refresh_time>cha){
                re_time = cha;
            }else {
                re_time = refresh_time;
            }
            return -1;
        }
        if(cha < 0){

        }
        if(video_refresh_callback_){
            video_refresh_callback_(frame);
        }else{

        }
        frame_queue_next_read(&vidfq);
    }


}

void FFPlayer::add_refresh_callback(std::function<int (const Frame *)> callback)
{
    this->video_refresh_callback_ = callback;
}

//void FFPlayer::add_refresh_callback(std::function<void (const Frame *)> callback)
//{
//    this->video_refresh_callback_ = callback;
//}



int FFPlayer::stream_componnet_open(int stream_index)
{
    int ret =0 ;
    AVCodecContext *avctx;
    AVCodec *avcdx ;
    int sample_rate;
    int nb_channels;
    int64_t channel_layout;
//    int vidindex=- 1

    avctx = avcodec_alloc_context3(NULL);
    //avcodec_parameters_to_context
    ret = avcodec_parameters_to_context(avctx,this->avfmt->streams[stream_index]->codecpar);
    if(ret<0){
        std::cout<<__FUNCTION__<<"avcodec_parameters_copy error"<<std::endl;
        return -1;
    }
//    AVCodec *avcdx =NULL;
    avcdx= avcodec_find_decoder(avctx->codec_id);
    if(!avcdx){
        std::cout<<__FUNCTION__<<"avcodec_find_decoder error"<<std::endl;
        return -2;
    }

    ret = avcodec_open2(avctx,avcdx,NULL);
    if(ret < 0){
        std::cout<<__FUNCTION__<<"avcodec_open2 error"<<std::endl;
        return -3;
    }
    //Decoder* decoder = new Decoder();
    //代码有一段复制tb的先不写
    switch (avctx->codec_type) {
    case AVMEDIA_TYPE_AUDIO:
        std::cout<<__FUNCTION__<<":AVMEDIA_TYPE_AUDIO"<<std::endl;
        //this->audcoder =
        //avctx->channel_layout;
        //audio_open(int wanted_freq, int wanted_layerout, int wanted_nb_chennel, AudioParams *tgt)
        audio_open(avctx->sample_rate,avctx->channel_layout,avctx->channels,&audio_tgt);
        audio_src = audio_tgt;
        this->audcoder.decoder_init(&this->audpq,avctx);
        ret = this->audcoder.decoder_start(AVMEDIA_TYPE_AUDIO,this);
        if(ret <0){
            std::cout<<__FUNCTION__<<"decoder start error"<<std::endl;
        }
        SDL_PauseAudio(0);
        index_audio = stream_index;
        st_audio = avfmt->streams[index_audio];
        break;
    case AVMEDIA_TYPE_VIDEO:
        this->videocoder.decoder_init(&vidpq,avctx);
        this->videocoder.decoder_start(AVMEDIA_TYPE_VIDEO,this);
        index_video = stream_index;
        vidindex = index_video;
        st_video = avfmt->streams[index_video];
        std::cout<<__FUNCTION__<<":AVMEDIA_TYPE_VIDEO"<<std::endl;

        break;
    default:
        avcodec_free_context(&avctx);
        std::cout<<__FUNCTION__<<":orther"<<std::endl;
    //临时加入
        break;
    }
    //临时插入

    //暂时没搞好.

//    avcodec_free_context(&avctx);
    return 1;
}

int FFPlayer::stream_componnet_close(int stream_index)
{
    //释放decoder的

    return 0;
}

static int audio_decode_frame(FFPlayer *ffp){
    //从framequeue中取出frame,进行重采样,然后放入缓冲区
//    if(ffp->paused){
//        return -1;
//    }
    int re_size =0;
    int data_size =0;
    int src_channel_layout;
    int wanted_nb_samples;
    Frame *f;
    do{
        frame_queue_get_readable(&ffp->audfq,&f);

        frame_queue_next_read(&ffp->audfq);
if(f->frame->sample_rate == 0){
    std::cout<<std::endl;
}
    }while(f->serial != ffp->audpq.serial);
    std::cout<<"text"<<std::endl;
    //获取源 声道信息
// if(f->frame->)
    src_channel_layout = f->frame->channel_layout && (f->frame->channels == av_get_channel_layout_nb_channels(f->frame->channel_layout)) ? f->frame->channel_layout :
        av_get_default_channel_layout(av_get_channel_layout_nb_channels(f->frame->channel_layout));

    wanted_nb_samples = f->frame->nb_samples;
    data_size = av_samples_get_buffer_size(NULL, av_frame_get_channels(f->frame),
                                           f->frame->nb_samples,
                                           (enum AVSampleFormat)f->frame->format, 1);
    if(ffp->audio_tgt.channel_layout != src_channel_layout ||
            ffp->audio_tgt.fmt != f->frame->format ||
            ffp->audio_tgt.freq != f->frame->sample_rate ||
            (wanted_nb_samples == f->frame->nb_samples && !ffp->swr_ctx)){
        //
        swr_free(&ffp->swr_ctx);
        ffp->swr_ctx = swr_alloc_set_opts(NULL,
                           ffp->audio_tgt.channel_layout,ffp->audio_tgt.fmt,ffp->audio_tgt.freq,
                           src_channel_layout,(enum AVSampleFormat)f->frame->format, f->frame->sample_rate,
                           0,NULL);
       int ret =0 ;
       ret = swr_init(ffp->swr_ctx);
       if(ret<0){
            return -1;
       }
       ffp->audio_src.fmt=(enum AVSampleFormat) f->frame->format;
       ffp->audio_src.channels = f->frame->channels;
       ffp->audio_src.channel_layout =  src_channel_layout;
       ffp->audio_src.freq = (enum AVSampleFormat)f->frame->sample_rate;
       if(ffp->audio_src.freq == 0 ){
           std::cout<<"kongzhe"<<std::endl;
       }
    }
    if(ffp->swr_ctx){
        const uint8_t **in = (const uint8_t **)f->frame->extended_data;

        uint8_t **out = &ffp->audio_buff1.buff;
        //计算输出多少个采样点
        int out_count = f->frame->nb_samples*ffp->audio_tgt.freq/ffp->audio_src.freq + 256;
        //计算输出需要多大的缓冲区
        int out_size = av_samples_get_buffer_size(NULL,ffp->audio_tgt.channels,out_count,ffp->audio_tgt.fmt,0);
        //分配缓冲区
        av_fast_malloc(&ffp->audio_buff1.buff ,&(ffp->audio_buff1.buffsize),out_size);
        if(ffp->audio_buff1.buff == NULL){
            std::cout<<__FUNCTION__<<"av_fast_malloc error"<<std::endl;
            return -1;
        }
        int len2=0;

        len2 = swr_convert(ffp->swr_ctx,out,out_count,in,f->frame->nb_samples);
        if(len2 == out_count){
            std::cout<<__FUNCTION__<<"重采样了:"<<len2<<"采样点"<<std::endl;
        }

//        constnt **in
        ffp->audio_buff = ffp ->audio_buff1;
        re_size = len2*ffp->audio_tgt.channels*av_get_bytes_per_sample(ffp->audio_tgt.fmt);
    }else{
        ffp->audio_buff.buff = f->frame->data[0];
        re_size = data_size;
    }
//    ffp->master_clock.set_clock();
    //此帧时间

    ffp->audio_time_n = f->pts + f->frame->nb_samples / f->frame->sample_rate;
    ffp->audio_buff.buffsize = re_size;
//    ffp->audio_time_n = z
    return 0;

}

static void sdl_audio_callback(void *opae ,Uint8 *stream ,int len)
{
    FFPlayer *ffp = (FFPlayer*)opae;
    int len1=0;
    int ret =0;
    std::cout<<__FUNCTION__<<"callback !!!!!"<<std::endl;
    //根据还需要拷贝多少数据作为条件,不断填充stream,直到满为止
    while(len>0){
       //根据缓冲区情况进行判断,从缓冲区取数据到stream,如果缓冲区数据不够,填充不满就从framequeue中取数据到缓冲区
        if(ffp->buff_index>=ffp->audio_buff.buffsize){
            ret = audio_decode_frame(ffp);

            //缺少frame,或者已经复制过了
            if(ret<0){
               ffp->audio_buff = NULL;
               ffp->audio_buff.buffsize = SDL_AUDIO_MIN_BUFFER_SIZE / ffp->audio_tgt.frame_size
                       * ffp->audio_tgt.frame_size;

            }else{

            }
            ffp->buff_index = 0 ;
        }
        //首先判断缓冲区有没有数据,如果没有调用函数取出

        //这里我没记错的化时做转换播放的.那暂时就不管他

        if(0==ffp->audio_buff.buffsize){
            continue;
        }

        //从缓冲区取出数据复制到stream中,这里涉及到缓冲区大小,如果大于stream则只复制stream大小的,然后调整索引.
        //如果小于len,则取出当前数据再次并且调整len,进入下一个循环,那么是否需要取frame到缓冲区的条件就是index有没有大于大小
        len1 = ffp->audio_buff.buffsize - ffp->buff_index;
        if(len1>len){
            len1=len;
        }
        if(ffp->audio_buff.buff ){
            memcpy(stream,(uint8_t *)ffp->audio_buff.buff+ffp->buff_index,len1);
    //        memcpy(stream,(uint8_t *)ffp->audio_buff.buff+ffp->buff_index,len1);
//            len -=len1;
//            ffp->buff_index +=len1;
//            stream += len1;
        }else{
            memset(stream,0,len1);
//            if (ffp->audio_buff.buff) {
//                SDL_MixAudio(stream, (uint8_t *)is->audio_buf + is->audio_buf_index, len1, is->audio_volume);
//            }
        }
        len -=len1;
        ffp->buff_index +=len1;
        stream += len1;

    }
    //
    double time = av_gettime_relative() / 1000000.0;
    ffp->master_clock.set_clock(ffp->audio_time_n,time);
    std::cout<<__FUNCTION__<<"stream full" <<std::endl;
    
//    ffp->master_clock.set_clock();

}

int FFPlayer::audio_open(int wanted_freq, int wanted_layerout, int wanted_nb_chennel, AudioParams *tgt)
{
//    int ret =-1;
    SDL_AudioSpec wanted_spec;
    wanted_spec.channels = wanted_nb_chennel;
    wanted_spec.freq = wanted_freq;
    wanted_spec.callback = sdl_audio_callback;
    wanted_spec.format = AUDIO_S16SYS;
    wanted_spec.silence = 100;
    wanted_spec.samples = 2048;//需要调整
    wanted_spec.userdata = this;

   int ret = SDL_OpenAudio(&wanted_spec,NULL);
   if(ret < 0){
       std::cout<<"open sdl_auido error"<<SDL_GetError()<<std::endl;
//       st
//       printf("SDL_OpenAudio error: %s\n", SDL_GetError());
       return -1;
   }
    tgt->freq = wanted_spec.freq;
    tgt->channels = wanted_nb_chennel;
    tgt->channel_layout = wanted_spec.channels = wanted_layerout;
    tgt->fmt = AV_SAMPLE_FMT_S16;
    tgt->frame_size = av_samples_get_buffer_size(NULL,wanted_nb_chennel,1,tgt->fmt,0);
    if(tgt->frame_size<=0){
        std::cout<<__FUNCTION__<<"erooro"<<std::endl;
    }
    tgt->bytes_per_sec= av_samples_get_buffer_size(NULL,wanted_nb_chennel,1,tgt->fmt,0);
    if( tgt->bytes_per_sec<=0){
        std::cout<<__FUNCTION__<<"error"<<std::endl;
    }


    return wanted_spec.size;



}



Decoder::Decoder()
{

}

Decoder::~Decoder()
{

}

void Decoder::decoder_init(PakcetQueue *pqm, AVCodecContext *ctx)
{
    avcdx_ = ctx;
    pq_ = pqm;
    //this->avcdx_ = ctx;
}
//arg = ffplayer
int Decoder::decoder_start(AVMediaType type, void *arg)
{
    FFPlayer *ffp = (FFPlayer*) arg;
    int ret = 0 ;
    if(ffp->is_netstream){
        this->decoder_reorder_pts = 1;
    }
    ret =  packet_queue_start(pq_);
    //ret = pakcet_queue_start(this->pq_);
    if(type == AVMEDIA_TYPE_AUDIO){
       this->decoder_thread_ = new std::thread(this->audio_thread,this,arg);
    }else if(type == AVMEDIA_TYPE_VIDEO){
       this->decoder_thread_ = new std::thread(this->video_thread,this,arg);
        std::cout<<__FUNCTION__<<"AVMEDIA_TYPE_VIDEO "<<std::endl;
    }else{
        return -1;
    }
    return 0;

}

int Decoder::decoder_decode_frame(AVFrame *frame)
{
    AVPacket pkt;
    int ret =0 ;
    for(;;){
        if(this->pq_->abort_request){
            return -1;
        }
        do{
            //std::cout<<"debuger point"<<std::endl;

            if(avcdx_->codec_type == AVMEDIA_TYPE_AUDIO){
                //写入framequeue中
                ret = avcodec_receive_frame(avcdx_,frame);
                if(ret>=0){
                    AVRational tb = {1,frame->sample_rate};
                /*
                把pts转化成以采样率作为时间基,可以根据frame所在位置推测pts,用于获取pts等于av_nopte_value,
                最后在外面转换成以秒作为时间基,进行同步
                */
                    if(frame->pts != AV_NOPTS_VALUE){
                        frame->pts = av_rescale_q(frame->pts,this->avcdx_->time_base,tb);
                    }else if(this->next_pts != AV_NOPTS_VALUE){
                        frame->pts = av_rescale_q(frame->pts,this->avcdx_->time_base,this->next_pts_tb);
                    }
                    if(frame->pts != AV_NOPTS_VALUE){
                        next_pts = frame->pts+frame->nb_samples;
                        next_pts_tb = tb;
                    }
                }
            }else if(avcdx_->codec_type == AVMEDIA_TYPE_VIDEO){
                ret = avcodec_receive_frame(avcdx_,frame);
                if(ret>=0){
                    if(decoder_reorder_pts){
                        frame->pts = frame->best_effort_timestamp;
                    }else{
                        frame->pts = frame->pkt_dts;
                    }
                    //break;
                }
            }else{
                av_frame_free(&frame);
            }
        //读取到文件尾部
            if(ret== AVERROR_EOF){
                this->finished_ = this->serial_;
                std::cout<<"E!O!F!"<<std::endl;
                avcodec_flush_buffers(this->avcdx_);
                return 0;
            }
            if(ret>=0){
                if(avcdx_->codec_type == AVMEDIA_TYPE_VIDEO){
                   std::cout<<std::endl ;
                }
                return 1;
            }
        }while(ret != AVERROR(EAGAIN));
        //阻塞读取
        do{
            if(this->packet_pending_){
//                av_packet_move_ref()
                this->packet_pending_ = 0;
            }else{
//                if(pq)
                ret= packet_queue_get(this->pq_ , &pkt, 1, &this->serial_);
                 if(avcdx_->codec_type == AVMEDIA_TYPE_VIDEO);
                if(ret<=0){
                    if(ret==-1){
                        std::cout<<"包队列空"<<std::endl;
                    }else if(ret<-1){
                        std::cout<<"包与队列srial不同,已释放:"<<ret+1<<"个包"<<std::endl;
                    }
                }
            }
            if(this->pq_->serial!=this->serial_){
                av_packet_unref(&pkt);
                std::cout<<__FUNCTION__<<"序列不对"<<std::endl;

            }
        }while(this->pq_->serial!=this->serial_);

        if(pkt.data == flush_pkt.data){
            avcodec_flush_buffers(avcdx_);
            finished_ =0;
            next_pts = start_pts;
            next_pts_tb = start_pts_tb;
        }else{
            ret = avcodec_send_packet(this->avcdx_,&pkt);
            if(ret  == AVERROR(EAGAIN)){
                this->packet_pending_ = 1;
            }else {
                av_packet_unref(&pkt);
            }
        }
//        if(pkt.data == NULL){
//            continue;
//        }

//        ret = avcodec_send_packet(this->avcdx_,&pkt);
//        if(ret  == AVERROR(EAGAIN)){
//            this->packet_pending_ = 1;
//        }else {
//            av_packet_unref(&pkt);
//        }
        
    }
    std::cout<<"1"<<std::endl;
               ;

}

int Decoder::audio_thread(void *arg)
{

    FFPlayer *ffp = (FFPlayer*)arg;
    AVFrame *frame=av_frame_alloc();
    Frame *f=NULL;
//    frame=av_frame_alloc();
    int ret =0;
    std::cout<<"1"<<std::endl;
    //尝试从解码器中取出frame
    for(;;){
        if(ffp->abort_request){
            ret = -2;
            break;
        }
        int ret = 0;
        ret = decoder_decode_frame(frame);
        if(ret<0){
             //return -1;
            break;
        };
        if (ret == 0) continue;
        //Frame *f;
        ret = frame_queue_get_wirtable(&ffp->audfq,&f);
        //f->frame = frame;
        f->pts = (frame->pts == AV_NOPTS_VALUE) ? NAN : frame->pts *av_q2d(AVRational{1,frame->sample_rate});
        f->duration = av_q2d(AVRational{frame->nb_samples,frame->sample_rate});
        f->serial = serial_;
        f->pos = frame->pkt_pos;
        av_frame_move_ref(f->frame,frame);
        frame_queue_next_wirte(&ffp->audfq);

    }

    av_frame_free(&frame);
    if(ret<0){
        std::cout<<__FUNCTION__<<"error exit"<<std::endl;
        return -1;
    }

    return 0;
}
//typedef struct Frame {
//    AVFrame		*frame;         // 指向数据帧
//    double		pts;            // 时间戳，单位为秒
//    double		duration;       // 该帧持续时间，单位为秒
//    int       pos;                // 偏移量
//    int		serial;
//    int		width;              // 图像宽度
//    int		height;             // 图像高读
//    int		format;             // 对于图像为(enum AVPixelFormat)
//}Frame;
int Decoder::video_thread(void *arg)
{
    FFPlayer *ffp = (FFPlayer*)arg;
    AVFrame *avframe=av_frame_alloc();
    int ret = 0;
    double pts = NAN;
    double duration =0 ;
    Frame *frame;
    AVRational frame_rate = av_guess_frame_rate(ffp->avfmt,ffp->st_video,NULL);
    AVRational tb = ffp->st_video->time_base;
    for(;;){
        if(ffp->abort_request){
            break ;
        }
        ret = decoder_decode_frame(avframe);
        if(ret<0){
            break;
        } else if(0 == ret){
            continue;
        }

        if(frame_rate.den && frame_rate.num){
            duration = av_q2d((AVRational){frame_rate.den ,frame_rate.num});
        }
        if(avframe->pts != AV_NOPTS_VALUE){
            pts = (avframe->pts) * av_q2d(tb);
        }
//        duration = (frame_rate.den && frame_rate.num)? av_q2d(AVRational{frame_rate.den ,frame_rate.num}): 0;
//        pts = (avframe->pts == AV_NOPTS_VALUE) ? NAN : (avframe->pts) * av_q2d(tb);

        ret = frame_queue_get_wirtable(&ffp->vidfq,&frame);
        if(ret < 0 ){
            break;

        }
        frame->duration  = duration;
        frame->format    = avframe->format;
        frame->height    = avframe->height;
        frame->width     = avframe->width;
        frame->pos       = avframe->pkt_pos;
        frame->pts       = pts;
        frame->serial    = serial_;

        av_frame_move_ref(frame->frame,avframe);
        frame_queue_next_wirte(&ffp->vidfq);
        av_frame_unref(avframe);
    }
    std::cout<<"exit" << __FUNCTION__ <<std::endl;
    av_frame_free(&avframe);
    return 0;
}

//int Clock::set_clock(double pts,int64_t time)
//{
//    this->
//    this->drfme = pts
//}


Clock::Clock()
{

}

int Clock::set_clock(double pts, double time)
{
    this->last_uplate = time ;
    this ->pts = pts;
    this ->drfme = pts - time;
}

double Clock::get_clock()
{
    return this->drfme;
}
